﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace ChineseChess.Game.AI
{
    public class Ai5 : BaseAi
    {

        private static int treeDepth;
        /// <summary>
        /// Ai的算法(Ai5为Ai1到Ai7中最好的Ai)
        /// </summary>
        /// <param name="pieceList">当前局面</param>
        /// <param name="canvas"></param>
        /// <param name="deep">计算深度</param>
        public static void Run(List<Piece> pieceList, Canvas canvas, int deep = 4)
        {
            List<Piece> pies = pieceList;
            treeDepth = deep;

            initTable2();
            Moves mv = getAlphaBeta(-9999, 9999, deep, pies, false);

            if (mv == null || mv.score == -8888)
            {
                treeDepth = 2;
                mv = getAlphaBeta(-9999, 9999, treeDepth, pies, false);
            }

            Piece p = clearPiece(pieceList, (int)mv.p.X, (int)mv.p.Y);//吃掉子
            //MessageBox.Show(mv.pie.Name.ToString() + mv.pie.X + "," + mv.pie.Y + ", " + mv.p.ToString());
            if (p != null)
            {
                canvas.Children.Remove(p);
            }

            for (int i = 0; i < pieceList.Count; i++)
            {
                var pie = pieceList[i];
                if (pie.X == mv.pie.X && pie.Y == mv.pie.Y)
                {
                    pie.X = (int)mv.p.X;
                    pie.Y = (int)mv.p.Y;
                    pie.InvalidateVisual();
                }
            }
        }

        private static Moves rootKey;
        private static Moves getAlphaBeta(int A, int B, int depth, List<Piece> pies, bool isred)
        {
            if (depth == 0)
            {
                Moves mv = new Moves();
                mv.score = evaluate(pies, isred);
                return mv;
            }
            var moves = generateMoves(pies, isred); //生成全部走法

            Moves move = null;
            for (int i = 0; i < moves.Count; i++)
            {
                move = moves[i];
                Piece pie = move.pie;
                int oldX = move.pie.X;
                int oldY = move.pie.Y;
                int newX = (int) move.p.X;
                int newY = (int)move.p.Y; 
                Moves historyMv = null;
                Piece eatedPie = MovePie(pies, move, out historyMv);
                pie.X = newX;
                pie.Y = newY;

                if (eatedPie!=null && eatedPie.Name == ChessName.将)
                {   //被吃的是老将，撤销这个走法
                    BackMovePie(pies, eatedPie, historyMv);
                    Moves mv = move;
                    mv.score = 8888;
                    return mv;
                }
                else
                {
                    var val = -getAlphaBeta(-B, -A, depth - 1, pies, !isred).score;

                    //撤销这个走法
                    BackMovePie(pies,eatedPie,historyMv);

                    if (val >= B)
                    {
                        Moves mv = move;
                        mv.score = B;
                        return mv;
                    }
                    if(val > A)
                    {
                        A = val; //设置最佳走法
                        if(treeDepth == depth)
                        {
                            rootKey = move;
                            rootKey.score = A;
                        }
                    }
                    if (A >= B)
                    {   //剪枝
                        break;
                    }
                } 
            }

            if (treeDepth == depth)
            {
                if (rootKey == null)
                {   //被将死
                    return null;
                }
                else
                {
                    return rootKey;
                }
            }
            Moves mv2 = move;
            mv2.score = A;
            return mv2;
        }
        
    }
}
